#include "lista.h"

template <typename T>
Lista<T>::Lista()
{
    Primero=NULL;
}
template <typename T>
Lista<T> Lista<T>::operator =(Lista<T> copy)
{
    Lista<T> Temp;
    Nodo<T>* aux=copy.Primero;
    while (aux) {
        Temp.InsertarFinal(aux->getValor(),aux->getContenedor());
        aux=aux->getSiguiente();
    }
    return Temp;
}
template <typename T>
bool Lista<T>::Vacia()
{
    return Primero==NULL;
}
template <typename T>
int Lista<T>::Largo()
{
    int ret =0;
    Nodo<T>* Aux = Primero;
    while(Aux)
    {
        ret++;
        Aux=Aux->getSiguiente();
    }
    return ret;
}
template <typename T>
void Lista<T>::InsertarInicio(int v, T c)
{
    if(Vacia())
        Primero=new Nodo<T>(v,c);
    else
    {
        Primero=new Nodo<T>(v,c,Primero);
        Primero->getSiguiente()->setAnterior(Primero);
    }

}
template <typename T>
void Lista<T>::InsertarFinal(int v, T c)
{
    if (Vacia())
        Primero=new Nodo<T>(v,c);
    else
    {
        Nodo<T>* Aux=Primero;
        while(Aux->getSiguiente())
            Aux=Aux->getSiguiente();
        Aux->setSiguiente(new Nodo<T>(v,c,NULL,Aux));
    }
}
template <typename T>
void Lista<T>::InsertarPos(int v, T c, int pos)
{
    if(Vacia())
        Primero=new Nodo<T>(v,c);
    else if(pos<=1)
        InsertarInicio(v,c);
    else if(pos>Largo())
        InsertarFinal(v,c);
    else
    {
        Nodo<T>* Aux = Primero;
        int cont = 2;
        while(cont!=pos && Aux->getSiguiente())
        {
            cont++;
            Aux=Aux->getSiguiente();
        }
        Nodo<T>* Nuevo = new Nodo<T>(v,c,Aux->getSiguiente(),Aux);
        Aux->setSiguiente(Nuevo);
        Aux->getSiguiente()->getSiguiente()->setAnterior(Nuevo);
    }
}
template <typename T>
void Lista<T>::EliminarInicio()
{
    if(Vacia())
        std::cout<<"Vacia"<<std::endl;
    else
    {
        Nodo<T>* Temp = Primero;
        Primero=Primero->getSiguiente();
        Primero->setAnterior(NULL);
        delete Temp;
    }
}
template <typename T>
void Lista<T>::EliminarFinal()
{
    if (Vacia())
        std::cout<<"Vacia"<<std::endl;
    else if(Primero->getSiguiente()==NULL)
    {
        Nodo<T>* Aux = Primero;
        Primero = NULL;
        delete Aux;
    }
    else
    {
        Nodo<T>* Aux = Primero;
        while(Aux->getSiguiente()->getSiguiente())
            Aux=Aux->getSiguiente();
        Nodo<T>* Temp = Aux->getSiguiente();
        Aux->setSiguiente(NULL);
        delete Temp;
    }
}
template <typename T>
void Lista<T>::EliminarPos(int pos)
{
    if (Vacia())
        std::cout<<"Vacia"<<std::endl;
    else if(pos<1 || pos>Largo())
        std::cout<<"pos invalida"<<std::endl;
    else if (pos==1)
        EliminarInicio();
    else if(pos==Largo())
        EliminarFinal();
    else
    {
        Nodo<T>* Aux = Primero;
        for(int i = 2;i<pos; i++)
            Aux=Aux->getSiguiente();
        Nodo<T>* Temp = Aux->getSiguiente();
        Aux->setSiguiente(Aux->getSiguiente()->getSiguiente());
        Aux->getSiguiente()->setAnterior(Aux);
        delete Temp;
    }
}
template <typename T>
bool Lista<T>::Valido(int v)
{
    if(Vacia())
        return false;
    else
    {
        Nodo<T>* Aux = Primero;
        while(Aux)
        {
            if(Aux->getValor()==v)
                return true;
            else
                Aux=Aux->getSiguiente();
        }
        return false;
    }
}
template <typename T>
bool Lista<T>::Valido(T c)
{
    if(Vacia())
        return false;
    else
    {
        Nodo<T>* Aux = Primero;
        while(Aux)
        {
            if(Aux->getContenedor()==c)
                return true;
            else
                Aux=Aux->getSiguiente();
        }
        return false;
    }
}
template <typename T>
Nodo<T>* Lista<T>::Buscar(int v)
{
    if(Vacia())
        return NULL;
    else
    {
        Nodo<T>* Aux = Primero;
        while(Aux)
        {
            if(Aux->getValor()==v)
                return Aux;
            else
                Aux=Aux->getSiguiente();
        }
        return NULL;
    }
}
template <typename T>
Nodo<T>* Lista<T>::Buscar(T c)
{
    if(Vacia())
        return NULL;
    else
    {
        Nodo<T>* Aux = Primero;
        while(Aux)
        {
            if(Aux->getContenedor()==c)
                return Aux;
            else
                Aux=Aux->getSiguiente();
        }
        return NULL;
    }
}
template <typename T>
Nodo<T>* Lista<T>::operator [](int pos)
{
    if(Vacia())
        return NULL;
    if (pos<1 || pos>Largo())
        return NULL;
    Nodo<T>* Aux = Primero;
    for (int i=1;i<pos;i++)
        Aux=Aux->getSiguiente();
    return Aux;
}
template <typename T>
T Lista<T>::Index(int c)
{
    return Buscar(c)->getContenedor();
}
template <typename T>
QString Lista<T>::ToQString()
{
    QString ret ="";
    Nodo<T>* Aux=Primero;
    while(Aux)
    {
        ret+= QString::number(Aux->getValor())+ " ";
        Aux=Aux->getSiguiente();
    }
    return ret;
}


//template class Lista<Lista<hola>* >;
template class Lista<unsigned int>;
